package main;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;

import javax.swing.JFrame;

import model.impl.CentroidImpl;
import model.impl.IntersectionImpl3;

import org.resotc.model.ElementType;
import org.resotc.model.Intersection;
import org.resotc.model.Lane;
import org.resotc.model.Light;
import org.resotc.model.Queue;
import org.resotc.model.Track;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import participants.CarImpl;
import sim.display.Console;
import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.engine.SimState;
import sim.portrayal.continuous.ContinuousPortrayal2D;
import sim.portrayal.network.NetworkPortrayal2D;
import sim.portrayal.network.SimpleEdgePortrayal2D;
import sim.portrayal.network.SpatialNetwork2D;
import sim.portrayal.simple.OvalPortrayal2D;
import sim.portrayal.simple.RectanglePortrayal2D;
import sim.portrayal.simple.ShapePortrayal2D;
import sim.util.Double2D;

public class ResOTCView extends GUIState {

	private Logger log = LoggerFactory.getLogger(ResOTCView.class);

	ContinuousPortrayal2D environmentPortrayal = new ContinuousPortrayal2D();
	ContinuousPortrayal2D lanesPortrayal = new ContinuousPortrayal2D();
	ContinuousPortrayal2D trafficLightPortrayal = new ContinuousPortrayal2D();
	NetworkPortrayal2D streetsPortrayal = new NetworkPortrayal2D();
	ContinuousPortrayal2D carsPortrayal = new ContinuousPortrayal2D();
	ContinuousPortrayal2D lanePortrayal = new ContinuousPortrayal2D();

	public Display2D display;
	public JFrame displayFrame;
	private HashMap<Integer, Intersection> intersections;
	private Intersection intersection;

	public ResOTCView(SimState state) {
		super(state);
	}

	public ResOTCView() {
		super(new ResOTCModel(System.currentTimeMillis()));
	}

	public static String getName() {
		return "Resilient OTC system - Simulation";
	}

	public void start() {
		super.start();
		setupPortrayals();
	}

	public void load(SimState state) {
		super.load(state);
		setupPortrayals();
	}

	public void setupPortrayals() {
		ResOTCModel resOTCModel = (ResOTCModel) state;

		trafficLightPortrayal.setField(resOTCModel.trafficLightContinuous2D);
		for (Queue queue : resOTCModel.getTrafficQueueList()) {

			HashMap<Integer, Track> tracks = queue.getTracks();
			for (Track track : tracks.values()) {
				HashMap<Integer, Double2D> lights = queue.getTrafficLight()
						.getLightPos();

					if (track.getElementType() == ElementType.INCOMING) {
						Color color = queue.getTrafficLight().getColor(
								queue.getTrackLightId(track.getId()));
						Light tl = queue.getTrafficLight().getLight(queue.getTrackLightId(track.getId()));
						
						Double2D lightPos = queue.getTrafficLight().getLightPos().get(queue.getTrackLightId(track.getId()));
						System.out.println(queue.getTrackLightId(track.getId()));
						System.out.println(queue.getTrafficLight().getLightPos());
						trafficLightPortrayal.setPortrayalForObject(lightPos,tl);
						resOTCModel.trafficLightContinuous2D.setObjectLocation(tl, lightPos);
					}
				}
		
		}
		lanesPortrayal.setField(resOTCModel.laneContinuous2D);
		for (Lane lane : resOTCModel.getLaneList()) {
			double[] xPointsLane2 = lane.getShapeXCoordinates();
			double[] yPointsLane2 = lane.getShapeYCoordinates();
			// be careful, shapes are overwritten!
			ShapePortrayal2D shape = new ShapePortrayal2D(xPointsLane2,
					yPointsLane2, Color.gray);
			lanesPortrayal.setPortrayalForObject(lane, shape);
			resOTCModel.laneContinuous2D.setObjectLocation(lane,
					lane.getCenter());
		}

		// tell the portrayals what to portray and how to portray them
		environmentPortrayal.setField(resOTCModel.getEnvironment());

		double[] xPoints = { 5, -5, -5, 5 };
		double[] yPoints = { -5, -5, 5, 5 };
		ShapePortrayal2D r2 = new ShapePortrayal2D(xPoints, yPoints,
				Color.magenta);
		environmentPortrayal.setPortrayalForClass(IntersectionImpl3.class, r2);

		carsPortrayal.setField(resOTCModel.cars);
		carsPortrayal.setPortrayalForClass(CarImpl.class,
				new sim.portrayal.simple.OvalPortrayal2D(Color.blue));

		RectanglePortrayal2D r1 = new RectanglePortrayal2D(Color.black, 4);

		// ShapePortrayal2D laneShape = new ShapePortrayal2D(xPointsLane,
		// yPointsLane, Color.yellow);
		Rectangle2D testrectangle = r2.shape.getBounds2D();
		OvalPortrayal2D o2 = new OvalPortrayal2D(Color.red, 2);

		// Traffic Light Dummy:
		OvalPortrayal2D trafficLight = new OvalPortrayal2D(Color.green, 2);

		// environmentPortrayal.setPortrayalForClass(LaneImpl.class, laneShape);

		environmentPortrayal.setPortrayalForClass(CentroidImpl.class, o2);
		// roadPortrayal.setField(new
		// SpatialNetwork2D(resOTCModel.getEnvironment(),
		// resOTCModel.getStreets()));
		// roadPortrayal.setPortrayalForAll(new SegmentPortrayal2D(false,
		// SegmentPortrayal2D.RIGHT_HAND_SIDE_OF_ROAD));

		streetsPortrayal.setField(new SpatialNetwork2D(resOTCModel
				.getEnvironment(), resOTCModel.getLanes()));
		streetsPortrayal.setPortrayalForAll(new SimpleEdgePortrayal2D());
		// reschedule the displayer
		display.reset();
		display.setBackdrop(Color.lightGray);

		// redraw the display
		display.repaint();
	}

	public void init(Controller c) {
		super.init(c);
		display = new Display2D(600, 600, this, 600);
		// display = new Display2D(600,600,this);
		display.setClipping(false);
		displayFrame = display.createFrame();
		displayFrame.setTitle("Traffic Network Simulation");
		c.registerFrame(displayFrame); // so the frame appears in the "Display"
										// list
		displayFrame.setVisible(true);

		display.attach(lanesPortrayal, "lanes");

		display.attach(carsPortrayal, "carsPortrayal");
		display.attach(environmentPortrayal, "Traffic Network");
		// display.attach(streetsPortrayal, "Streets");
		display.attach(lanePortrayal, "lane");
		display.attach(trafficLightPortrayal, "tl");

	}

	public static void main(String[] args) {
		ResOTCView resOTCView = new ResOTCView();
		Console c = new Console(resOTCView);
		c.setVisible(true);
	}
}
